"use strict";
var target = null; // 标记运行时函数
// 观察者定义
function Watcher(func) {
    target = func;
    target();
    target = null;
}
// 依赖类定义
var Dep = /** @class */ (function () {
    function Dep() {
        this.subscribers = []; // 初始化订阅者列表
    }
    // 添加数据的依赖
    Dep.prototype.depend = function () {
        // 保证订阅者的唯一性且只记录函数运行时的依赖
        if (target instanceof Function && !this.subscribers.includes(target)) {
            this.subscribers.push(target);
        }
    };
    // 更新所有依赖
    Dep.prototype.notify = function () {
        this.subscribers.forEach(function (sub) { return sub(); });
    };
    return Dep;
}());
// 映射哈希表
var depsMap = new Map();
// 获得响应式对象
function reactive(target) {
    // 为对象的每个属性都创建依赖类存储
    Object.keys(target).forEach(function (key) {
        depsMap.set(key, new Dep());
    });
    // 设置代理对象trap
    return new Proxy(target, {
        get: function (target, prop, receiver) {
            depsMap.get(prop).depend(); // 收集依赖
            return Reflect.get(target, prop, receiver);
        },
        set: function (target, prop, value, receiver) {
            var res = Reflect.set(target, prop, value, receiver);
            depsMap.get(prop).notify(); // 更新依赖
            return res;
        }
    });
}
// 测试用例
var product1 = {
    price: 10,
    discount: 0.9,
    quantity: 5
};
var proxy_product1 = reactive(product1);
var realPrice = 0;
var total2 = 0;
Watcher(function () { return total2 = proxy_product1.price * proxy_product1.quantity; });
Watcher(function () { return realPrice = proxy_product1.discount * proxy_product1.price; });
console.log(realPrice); // 9
console.log(total2); // 50
proxy_product1.quantity = 15;
console.log(total2); // 150
proxy_product1.price = 20;
console.log(realPrice); // 18
// 当在映射表中设置了新属性之后，proxy对象新添加的属性仍然是响应式的
depsMap.set("minus", new Dep());
var realPrice2 = 0;
proxy_product1.minus = 3;
Watcher(function () { return realPrice2 = proxy_product1.price - proxy_product1.minus; });
console.log(realPrice2); // 17
proxy_product1.minus = 5;
console.log(realPrice2); // 15
